package com.cogent.common.util;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import com.cogent.common.date.JodaDateUtil;
import com.cogent.common.exception.SystemRuntimeException;

/**
 * 提供对Map操作的封装，简化其操作.</br>
 * @author daiys 
 * @version 1.0<br/>
 * ****************************************************<br/>
 * 版本号	 修改日期		作者			更改原因<br/>
 * 1.0		2009-11-25	daiys		新增<br/>
 * ****************************************************<br/>
 */
public class MapUtil {

	/**
	 * 根据key获取对应的值
	 * @param map 获取值的map
	 * @param key 键
	 * @return 键值
	 */
	public static Object getValue(Map<?, ?> map, String key) {
		if(map.containsKey(key))
			return map.get(key);
		else
			return null;
	}
	
	public static boolean isNull(Map map, String key) {
		boolean flag = true;
		if(map.containsKey(key)){
			if(map.get(key) != null)
				flag = false;
		}
		
		return flag;
	}
	
	public static boolean isEmpty(Map map, String key) {
		boolean flag = isNull(map, key);
		if(!flag) {
			if(map.get(key).toString().length() < 1)
				flag = true;
		}
		
		return flag;
	}
	
	public static void mapToObject(Map map, Object bean) {
		Class<?> classType = bean.getClass();
		Field[] fields = classType.getDeclaredFields();
		for(int i=0; i<fields.length; i++) {
			Field field = fields[i]; 
            String fieldName = field.getName(); 
            String stringLetter = fieldName.substring(0, 1).toUpperCase();    
            String setName = "set"+stringLetter+fieldName.substring(1); 
            try {
				Method setMethod=classType.getMethod(setName, new Class[]{field.getType()});
				setMethod.invoke(bean, getValue(map, fieldName));    
			} catch (Throwable e) {
				throw new SystemRuntimeException(SystemRuntimeException.LOW, e.fillInStackTrace(), 
						"mapToObject设置对象值时错误", "mapToObject设置对象值时错误");
			}
		}
	}
	
	public static String getStringValue(Map map, String key) {
		if(!isNull(map, key)){
			String val=map.get(key).toString();
			
			return val;
		} 
		else
			return "";
		
	}
	
	public static String getStringValue(Map map, String key, String defvalue) {
		if(!isNull(map, key))
			return map.get(key).toString();
		else
			return defvalue;
		
	}
	
	public static Map replaceNull(Map map) {
		Map ret = new HashMap();
		Iterator it = map.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next().toString();
			
			String val=getStringValue(map, key);
//			if(key.equals("attributeoptionstore")){
//					val=val.replace("[\"", "{\"");
//					val=val.replace("\"]", "\"}");
//				}
			ret.put(key, val);
		}
		
		return ret;
	}
	
	public static int getIntValue(Map map, String key) {
		return getIntValue(map, key, 0);
	}
	
	public static long getLongValue(Map map, String key) {
		return getLongValue(map, key, 0l);	
	}
	
	public static long getLongValue(Map map, String key, long defValue) {
		if(!isEmpty(map, key)) {
			String curval = map.get(key).toString();
			if(curval.indexOf(".") > 0) {
				String[] temps = curval.split("\\.");
				curval = temps[0];
			}
			return Long.parseLong(curval);
		}else
			return defValue;		
	}
	
	public static double getDoubleValue(Map map, String key) {
		if(!isEmpty(map, key))
			return Double.parseDouble(map.get(key).toString());
		else
			return 0;		
	}
	
	public static int getIntValue(Map map, String key, int defValue) {
		if(!isEmpty(map, key)) {
			String curval = map.get(key).toString();
			if(curval.indexOf(".") > 0) {
				String[] temps = curval.split("\\.");
				curval = temps[0];
			}
			return Integer.parseInt(curval);
		}else
			return defValue;		
	}
	
	public static Object getObjectValue(Map map, String key) {
		Object obj = null;
		if(map.containsKey(key))
			obj = map.get(key);
		return obj;
	}
	
	public static void copyMapValue(Map mapValue, Map dataMap) {
		Iterator it = dataMap.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next().toString();
			mapValue.put(key, getStringValue(dataMap, key));
		}
	}
	
	public static void copyChangeMap(Map orgMap, Map destMap) {
		Iterator it = orgMap.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next().toString();
			if(destMap.containsKey(key))
				continue;
			destMap.put(key, getStringValue(orgMap, key));
		}
	}
	
	public static boolean isEqual(Map map, String key, String val) {
		String temp = getStringValue(map, key);
		return temp.equals(val);	
	}
	
	public static String getShortDate(Map map, String key) {
		String date = MapUtil.getStringValue(map, key);
		String ret = "";
		if(date.length() > 0)
			ret = JodaDateUtil.formatDateToString(date, "yyyy-MM-dd");
		
		return ret;
	}
	
	public static String getLongDate(Map map, String key) {
		String date = MapUtil.getStringValue(map, key);
		String ret = "";
		if(date.length() > 0)
			ret = JodaDateUtil.formatDateToString(date, "yyyy-MM-dd HH:mm:ss");
		
		return ret;
	}
	
	public static Date getDateValue(Map map, String key) {
		Date date = null;
		if(!MapUtil.isEmpty(map, key))
			date = JodaDateUtil.stringToDate(MapUtil.getStringValue(map, key));
		
		return date;
	}
	
	public static boolean isMapEquals(Map curMap, Map compareMap) {
		boolean flag = true;
		Iterator it = curMap.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next().toString();
			String curValue1 = getStringValue(curMap, key);
			String curValue2 = getStringValue(compareMap, key);
			if(!curValue1.equals(curValue2)) {
				flag = false;
				break;
			}
		}
		
		return flag;
	}
	
	public static Map clearNullValue(Map map) {
		Map retMap = new HashMap();
		Iterator it = map.keySet().iterator();
		while(it.hasNext()) {
			String key = it.next().toString();
			retMap.put(key, getStringValue(map, key));
		}
		
		return retMap;
	}
	
	public static String mapToJsonStr(Map map) {
		JSONArray json = JSONArray.fromObject(replaceNull(map)); 
    	return json.toString();
	}
	
	public static String mapToJsonPartyStr(Map map) {
		JSONArray json = JSONArray.fromObject(replaceNull(map)); 
		String temp = json.toString();
		if(temp.length() > 2) {
			temp = temp.substring(1);
			temp = temp.substring(0, temp.length()-1);
		}
    	return temp;
	}
	
	private static String genJsonContent(Map map) {
		JSONArray json = JSONArray.fromObject(map); 
    	return json.toString();
	}
	
	public static String listMapToJsonStr(List list) {
		if(list.size() == 0)
			return "[{}]";
		List curList = new ArrayList();
		for(int i=0; i<list.size(); i++)
			curList.add(replaceNull((Map)list.get(i)));
		JSONArray json = JSONArray.fromObject(curList); 
    	return json.toString();
	}
	
	public static List parseJSON2List(String jsonStr){
		 List ret = new ArrayList();
		 JSONArray jsonArr = JSONArray.fromObject(jsonStr);
		 for(int i=0; i<jsonArr.size(); i++) {
			 Map<String, Object> map = new HashMap<String, Object>();
			 JSONObject json = jsonArr.getJSONObject(i);
			 for(Object k : json.keySet()){
				 Object v = json.get(k); //如果内层还是数组的话，继续解析
				 if(v instanceof JSONArray){
					 List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
					 Iterator<JSONObject> it = ((JSONArray)v).iterator();
					 while(it.hasNext()){
						 JSONObject json2 = it.next();
						 list.add(parseJSON2Map(json2.toString()));
					 }
					 map.put(k.toString(), list);
				} else {
					map.put(k.toString(), v);
				}
			}
			if(map.size() > 0)
				ret.add(map);
		}
		 
		return ret;
	}
	 
	public static HashMap<String, Object> parseJSON2Map(String jsonStr){
		HashMap<String, Object> map = new HashMap<String, Object>();
		JSONArray jsonArr = JSONArray.fromObject(jsonStr);
		//最外层解析
		JSONObject json = jsonArr.getJSONObject(0);
		for(Object k : json.keySet()){
			Object v = json.get(k); 
			//如果内层还是数组的话，继续解析
			if(v instanceof JSONArray){
				List<Map<String, Object>> list = new ArrayList<Map<String,Object>>();
				Iterator<JSONObject> it = ((JSONArray)v).iterator();
				while(it.hasNext()){
					JSONObject json2 = it.next();
					list.add(parseJSON2Map(json2.toString()));
				}
				map.put(k.toString(), list);
			} else
				map.put(k.toString(), v);
		}
		return map;
	}
 }
